pub fn creat_boxed_u8_slice(size: usize) -> Box<[u8]>
{
    let vec = vec![0u8; size];
    vec.into_boxed_slice()
}

pub fn u16_to_u8_slice(u: u16) -> [u8; 2]
{ [(u >> 8) as u8, u as u8] }

pub fn u16_to_u8_slice_reverse(u: u16) -> [u8; 2]
{ [u as u8, (u >> 8) as u8] }

pub fn binary_slice_to_u8(binary: &[bool]) -> u8
{
    let mut result = 0;
    for x in binary {
        result <<= 1;
        if *x { result += 1; }
    }
    result
}

pub fn binary_str_to_u8(binary: &str) -> u8
{
    let mut result = 0;
    for x in binary.as_bytes() {
        result <<= 1;
        if x.eq(&49) { result += 1 }
    }
    result
}

pub fn double_u8_to_u16(left: u8, right: u8) -> u16 {
    let mut u = left as u16;
    u <<= 8;
    u += right as u16;
    u
}

pub fn char_to_u8(c: &char) -> Option<u8> {
    match c {
        '0' => { Some(0) }
        '1' => { Some(1) }
        '2' => { Some(2) }
        '3' => { Some(3) }
        '4' => { Some(4) }
        '5' => { Some(5) }
        '6' => { Some(6) }
        '7' => { Some(7) }
        '8' => { Some(8) }
        '9' => { Some(9) }
        'a' | 'A' => { Some(10) }
        'b' | 'B' => { Some(11) }
        'c' | 'C' => { Some(12) }
        'd' | 'D' => { Some(13) }
        'e' | 'E' => { Some(14) }
        'f' | 'F' => { Some(15) }
        _ => { None }
    }
}

/// 十六进制的char 两个一组转为u8 不正确的会返回空
pub fn x2u(l: &char, r: &char) -> Option<u8> {
    match (char_to_u8(l), char_to_u8(r)) {
        (Some(l), Some(r)) => { Some(l * 16 + r) }
        (_, _) => { None }
    }
}

/// 将String 转为每2个char一组 多余的会被舍弃
pub fn read_per_2char(s: &str) -> Vec<(char, char)> {
    let mut chars = s.chars();
    let mut v = vec![];
    while let (Some(l), Some(r)) = (chars.next(), chars.next()) { v.push((l, r)) }
    v
}

/// str to vec u8
pub fn s2v(s: &str) -> Option<Vec<u8>> {
    let v = read_per_2char(s);
    let mut vec = vec![];
    for (l, r) in v {
        match x2u(&l, &r) {
            None => { return None; }
            Some(u) => { vec.push(u); }
        };
    }
    Some(vec)
}

#[cfg(test)]
mod tests {
    use crate::util;
    use std::ops::Deref;

    #[test]
    fn test() {
        let slice = util::creat_boxed_u8_slice(4);
        for x in slice.deref() {
            println!("{}", x);
        }
    }

    #[test]
    fn test2() {
        println!("{:b} - {}", 0xff9b_u16, 0xff9b_u16);
        println!("{:b} - {}", 0xff9b_u16.wrapping_neg(), 0xff9b_u16.wrapping_neg());

        println!("{:b} - {}", 0x0001_u16, 0x0001_u16);
        println!("{:b} - {}", 0x0001_u16.wrapping_neg(), 0x0001_u16.wrapping_neg());
    }

    #[test]
    fn test3() {
        let i = util::binary_str_to_u8("11001001");
        assert_eq!(i, 201);

        let i = util::binary_slice_to_u8(&[true, true, false, false, true, false, false, true]);
        assert_eq!(i, 201);
    }

    #[test]
    fn test4() {
        let i = util::double_u8_to_u16(0x01, 0x10);
        println!("{} , {:x}", i, i);
    }

    #[test]
    fn test5() {
        let result = util::x2u(&'a', &'a').unwrap();
        println!("{} , {:x}", result, result);
        let vec = util::read_per_2char("01030000af0f");
        println!("{:?}", vec);
        let option = util::s2v("01030000af0f");
        println!("{:?}", option);
    }
}